import { ref, Ref, toValue, watchEffect, onUnmounted } from 'vue'
import { io, Socket } from 'socket.io-client'
import * as mediaClient from 'mediasoup-client'
import { types } from 'mediasoup-client'
import Debug from "debug"
export function useMediasoup(data: Ref<MediaStream | null>, videoHtml: Ref<HTMLMediaElement | null>) {
    const stream = ref<MediaStream | null>(null)
    const video = ref<HTMLMediaElement | null>(null)
    const debug = Debug('webrtc-mediasoup')
    const socket = ref<Socket | null>(null)
    const id = ref("")
    const rtp = ref<types.RtpCapabilities | null>(null)
    const device = ref<types.Device | null>(null)
    const producerTransport = ref<types.Transport | null>(null)
    const producer = ref<types.Producer | null>(null)
    const consumerTransport = ref<types.Transport | null>(null)
    const consumer = ref<types.Consumer | null>(null)
    watchEffect(() => {
        stream.value = toValue(data)
        video.value = toValue(videoHtml)
    })

    function init() {
        socket.value = io("https://127.0.0.1:3001/");
        const con = socket.value
        con.on('connectSuccess', e => {
            debug('连接成功 id:', e)
            id.value = e
        })
        con.on('disconnect', (e) => {
            debug('断开连接', e)
        })
    }
    function getRtp() {
        if (socket.value) {
            socket.value.emit('getRtpCapabilities', ({ rtpCapabilities }: { rtpCapabilities: types.RtpCapabilities }) => {
                debug('getRtpCapabilities', rtpCapabilities)
                rtp.value = rtpCapabilities
            })
        }
    }
    async function createDevice() {
        try {
            if (rtp.value) {
                const d = new mediaClient.Device()
                await d.load({
                    routerRtpCapabilities: rtp.value
                })
                device.value = d
                debug('创建device成功', d)
            }
        } catch (error) {
            debug('创建device失败', error)
        }

    }
    function createSendTransport() {
        if (socket.value) {
            socket.value.emit('createTransport', { sender: true }, ({ params, error }: { params: types.TransportOptions, error: any }) => {
                debug('params', params)
                if (error) {
                    debug('创建transport失败', error)
                    return
                }
                if (device.value) {
                    producerTransport.value = device.value.createSendTransport(params)
                    producerTransport.value.on('connect', async ({ dtlsParameters }, callback, errback) => {
                        if (socket.value) {
                            await socket.value.emit('transportConnect', { dtlsParameters })
                            callback()
                        } else {
                            errback(new Error('socket连接断开了'))
                        }
                    })
                    producerTransport.value.on('produce', async (params, callback, errback) => {
                        if (socket.value) {
                            await socket.value.emit('transportProduce', {
                                kind: params.kind,
                                rtpParameters: params.rtpParameters,
                                appData: params.appData
                            }, ({ id }: { id: string }) => {
                                callback({ id })
                            })
                        } else {
                            errback(new Error('socket连接断开了'))
                        }
                    })
                }
            })

        }
    }
    async function connectSendTransport() {
        if (producerTransport.value) {
            const track = stream.value?.getVideoTracks()[0]
            producer.value = await producerTransport.value.produce({
                // mediasoup params
                encodings: [
                    {
                        rid: 'r0',
                        maxBitrate: 100000,
                        scalabilityMode: 'S1T3',
                    },
                    {
                        rid: 'r1',
                        maxBitrate: 300000,
                        scalabilityMode: 'S1T3',
                    },
                    {
                        rid: 'r2',
                        maxBitrate: 900000,
                        scalabilityMode: 'S1T3',
                    },
                ],
                // https://mediasoup.org/documentation/v3/mediasoup-client/api/#ProducerCodecOptions
                codecOptions: {
                    videoGoogleStartBitrate: 1000
                },
                track
            })
            producer.value.on('trackended', () => {
                debug('track ended')

                // close video track
            })

            producer.value.on('transportclose', () => {
                debug('transport ended')

                // close video track
            })
        }
    }

    function createReceiveTransport() {
        if (socket.value) {
            socket.value.emit('createTransport', { sender: false }, ({ params, error }: { params: types.TransportOptions, error: any }) => {
                debug('params', params)
                if (error) {
                    debug('创建transport失败', error)
                    return
                }
                if (device.value) {
                    consumerTransport.value = device.value.createRecvTransport(params)
                    consumerTransport.value.on('connect', async ({ dtlsParameters }, callback, errback) => {
                        if (socket.value) {
                            await socket.value.emit('transportRecConnect', { dtlsParameters })
                            callback()
                        } else {
                            errback(new Error('socket连接断开了'))
                        }
                    })
                } else {
                    debug('没有device')
                }
            })

        }
    }
    async function connectReceiveTransport() {
        if (socket.value) {
            socket.value.emit('consume', {
                rtpCapabilities: device.value?.rtpCapabilities
            }, async ({ params, error }: { params: types.ConsumerOptions, error: any }) => {
                if (error) {
                    debug("connectReceiveTransport error")
                    return
                }
                debug(params)
                if (consumerTransport.value) {

                    consumer.value = await consumerTransport.value.consume({
                        id: params.id,
                        producerId: params.producerId,
                        kind: params.kind,
                        rtpParameters: params.rtpParameters
                    })
                    const { track } = consumer.value
                    if (video.value) {
                        video.value.srcObject = new MediaStream([track])
                        socket.value?.emit('consumer-resume')
                    }
                }
            })
        }

    }
    onUnmounted(() => {
        if (socket.value) {
            socket.value.close()
        }
    })
    debug('mediasoup 初始化')
    init()
    return {
        getRtp,
        createDevice,
        createSendTransport,
        createReceiveTransport,
        connectSendTransport,
        connectReceiveTransport
    }
}
